function ...
[encodedBitsM, codeBlocks, blocks,rateMatching] = WiSiL_Tx_channelCoding(bitsTx, encoder,transportBlockSize,wordSize,layers)
% WISIL_TX_CHANNELCODING Implement channel encoder.
%
% function bitsTxEncoded = channelCoding(bitsTx , encoder)
%
% This function applies the Channel Coding at an information bit sequence. 
% Several internal tools are performed when 'channelCoding' is called. 
% The following list contains all these tools:
%   - CRC (Cyclic Redundacy Check) attachment.
%   - Code Block Segmentation
%   - Convolutional Turbo Coding
%   - Rate Matching and bit selection
%   - Code Block Concatenation
%
% Syntax:
% INPUT PARAMETERS: 
%    -bitsTx: Information Bit Sequence to be transmitted.
%    -encoder: Structure containing all the parameters to be used by the
%    encoder.
%
% OUTPUT PARAMETERS: 
%    -bitsTxEncoded: Bit Sequence at the output of the Channel Coding
%    block.
%%%%

% History:
%   Rafhael Medeiros de Amorim ( rma.petit@gmail.com ), 12/02/2009
%     Created
%   Andre Noll Barreto, 11/03/2011
%     only CRC overhead included instead of actual CRC
%   Lucas Sousa e Silva 08/2014 - included ratematching functions
  
%--- Code Block Segmentation ----
[codeBlocks,blocks] = WiSiL_Encoder_blockSegmentation(bitsTx,encoder);
%---          ---           ----


encoded = cell(2,1); % Pre-Allocating Memory. 

if(strcmpi(encoder.FEC,'CTC')==1) % IF Turbo Coding is Used
    %----                       Turbo Coding                              ----%

    %Applying the Turbo Coding at the blocks of smaller length.
    if size(codeBlocks{1,1},1) >0
        for i = 1: size(codeBlocks{1,1},1)  % i = index of the Code Block
            %Encoding:
            encoded{i,1} = deal( WiSiL_Encoder_pccc( codeBlocks{1,1}(i,:), ...
                                                     encoder));

        end
    else
        i=0;
    end

    %Applying the Turbo Coding at the blocks of bigger length.
    for j = 1: size(codeBlocks{2,1},1); % j = index of the Code Block
        %Encoding:
        encoded{j+i,1} = deal(WiSiL_Encoder_pccc(codeBlocks{2,1}(j,:), encoder));
    end
    
   %-----------------------------RATEMATCHING------------------------------ 
    [rmBlocks,rateMatching] = WiSiL_Encoder_rateMatching(encoded,transportBlockSize,wordSize,layers);
    [ encodedBitsM ] = WiSiL_RM_Block_Concatenation(rmBlocks);
   %-----------------------------RATEMATCHING------------------------------
   
   
    %---                            ----                                 ---%

    %Update the BLOCKS parameters to the simulator
    K1 = blocks.K1; %Number of blocks with size C1.
    K2 = blocks.K2; %Number of blocks with size C2.
    fillerBits = blocks.fillerBits; %Number of filler bits.
    C2 = blocks.C2; %Size C2.
    %

    % This part of function is used to HARQ retransmission - It performs the
    % buffer of data bits (ready for retransmission) - discarding redundancy and filler bits.

    for k = 1:blocks.C1 + blocks.C2 % For each block
        if k <= blocks.C2 % If the block has size C2

            if k == 1 %If it is the 1st block, discard filler bits, and the block CRC attachment.
                auxiliar{1,1}(k,:) = codeBlocks{k,1}(k,fillerBits+1:K2-encoder.crc.sizeInBits);
            else
                if k == blocks.C1 + blocks.C2 %If is the last
                    %one discard the transport block CRC attachment and block CRC attachment.
                    auxiliar{k,1}(1,:) = codeBlocks{1,1}(k,1:K2-encoder.crc.sizeInBits);
                else %OtherWise, discard only the block CRC attachment.
                    auxiliar{k,1}(1,:) = codeBlocks{1,1}(k,1:K2-encoder.crc.sizeInBits);
                end
            end
        else % If the block has size C1
            if k == 1 %If it is the 1st block, discard filler bits, and the block CRC attachment.
                auxiliar{k,1}(1,:) = codeBlocks{2,1}(k-C2,fillerBits+1:K1 - encoder.crc.sizeInBits);
            elseif k == blocks.C1 + blocks.C2 %If is the last
                %one discard the transport block CRC attachment and block CRC attachment.
                auxiliar{k,1}(1,:) = codeBlocks{2,1}(k-C2,1:K1-encoder.crc.sizeInBits);
            else %OtherWise, discard only the block CRC attachment.
                auxiliar{k,1}(1,:) = codeBlocks{2,1}(k-C2,1:K1-encoder.crc.sizeInBits);
            end
        end
    end

    codeBlocks = auxiliar; % DATA BUFFER
    rateMatching.fillerBits = blocks.fillerBits;
 
else %If Turbo Coding is not used 
    encodedBits = WiSiL_Encoder_blockConcatenation(codeBlocks); %Concatenate the message blocks.
    % -- Discarding possible null bits: --
        auxiliar = isnan(encodedBits); 
        temp = (auxiliar == 1);
        encodedBits(temp) = [];
        codeBlocks = [];
    % --           ---                   --     
end